/* CsJni - .NET / Java Bridge
 * 
 * Copyright 2010 Robert E. Burke Licensed under the Apache License, Version 
 * 2.0 (the "License"); you may not use this file except in compliance with 
 * the License. You may obtain a copy of the License at 
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable 
 * law or agreed to in writing, software distributed under the License is 
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
 * KIND, either express or implied. See the License for the specific language 
 * governing permissions and limitations under the License. 
*/

using System;
using System.Collections.Generic;
using System.Text;

namespace CsJni
{
    internal sealed class JavaSystemPropertiesHelper
    {
        private JavaSystemPropertiesHelper() { }

        public static void LogBannerProperties(JniEnvironment environment)
        {
            Dictionary<string, string> properties = RetrieveAll(environment);

            JavaVM.Log("Current Java System Properties");

            string[] logPropNames = {
                "java.version",
                "java.vendor",
                "java.home",
                "java.vm.version",
                "java.vm.vendor",
                "java.vm.name",
                "java.class.version",
                "java.class.path",
                "java.library.path",
                "os.name",
                "os.arch",
                "os.version",
                "user.name",
                };

            foreach (string logPropName in logPropNames)
            {
                JavaVM.Log(logPropName + " = " + properties[logPropName]);
            }
        }

        public static Dictionary<string, string> RetrieveAll(JniEnvironment environment)
        {
            Dictionary<string, string> properties = new Dictionary<string,string>();

            JniLocalFrame frame = environment.CreateLocalFrame(1);
            try
            {
                JniClass systemClazz = JniClass.FindClass(environment, "java/lang/System");
                string[] keyNames = GetJavaPropertyNames(environment, systemClazz);
                JniMethod getPropMid = systemClazz.GetStaticMethodId(environment, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");

                foreach (string keyName in keyNames)
                {
                    JValue[] paramArray = new JValue[1];
                    paramArray[0].AssignStringValue(environment, keyName);
                    try
                    {
                        string val = getPropMid.CallStaticStringMethod(environment, paramArray);
                        properties.Add(keyName, val);
                    }
                    finally
                    {
                        paramArray[0].Free(environment);
                    }
                }
            }
            finally
            {
                frame.SafePop();
            }

            return properties;
        }

        private static string[] GetJavaPropertyNames(JniEnvironment environment, JniClass systemClazz)
        {
            JniLocalFrame frame = environment.CreateLocalFrame(6);
            try
            {
                JniMethod getPropsMid = systemClazz.GetStaticMethodId(environment, "getProperties", "()Ljava/util/Properties;");
                JniObject propsHandle = getPropsMid.CallStaticObjectMethod(environment, null);
                JniClass propsClazz = propsHandle.GetObjectClass(environment);
                JniMethod keySetId = propsClazz.GetMethodId(environment, "keySet", "()Ljava/util/Set;");
                JniObject setHandle = keySetId.CallObjectMethod(environment, propsHandle, null);
                JniClass setClazz = setHandle.GetObjectClass(environment);
                JniMethod toArrayId = setClazz.GetMethodId(environment, "toArray", "()[Ljava/lang/Object;");
                JniObjectArray arrayHandle = (JniObjectArray)toArrayId.CallObjectMethod(environment, setHandle, null);
                string[] keyNames = JniString.ExtractStringArray(environment, arrayHandle);
                return keyNames;
            }
            finally
            {
                frame.SafePop();
            }
        }
    }
}
